package se.webbzon.boltzmann.minigame.cells;

import java.awt.Color;
import java.awt.Rectangle;

import se.webbzon.boltzmann.camera.AbstractCamera;
import se.webbzon.boltzmann.debug.Debug;
import se.webbzon.boltzmann.environment.DefaultEnvironment;
import se.webbzon.boltzmann.input.Input;
import se.webbzon.boltzmann.minigame.Puzzle;
import se.webbzon.boltzmann.minigame.chemistry.Electrolysis;
import se.webbzon.boltzmann.minigame.chemistry.Gasoline;
import se.webbzon.boltzmann.minigame.machine.MachinePart;
import se.webbzon.boltzmann.minigame.machine.SandBoxMachine;
import se.webbzon.boltzmann.minigame.sandbox.DefaultSandBox;
import se.webbzon.boltzmann.minigame.sandbox.SandBox;
import se.webbzon.boltzmann.minigame.sandbox.SandBoxButton;
import se.webbzon.boltzmann.minigame.sandbox.SandBoxCursor;
import se.webbzon.boltzmann.minigame.sandbox.SandBoxItem;
import se.webbzon.boltzmann.minigame.sandbox.SandBoxSpawner;
import se.webbzon.boltzmann.resource.Resources;
import se.webbzon.boltzmann.timer.Timer;
import se.webbzon.boltzmann.timer.TimerListener;
import se.webbzon.boltzmann.world.DefaultWorldLoader;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldcamera.WorldView;

public class CellGame extends Puzzle {
	
	private SandBoxItem[] equipment;
	
	private int equipmentIndex;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public CellGame() {
		super("puzzles/cells");
	}
	
	/*============================================================
	Protected Methods
	============================================================*/

	@Override protected WorldArea loadPuzzle(WorldView view, Input input) {
		try {
			DefaultEnvironment env = new DefaultEnvironment();
			DefaultWorldLoader loader = new DefaultWorldLoader(env,"euler/r102");
			WorldArea world = loader.load();
			//DummyCamera camera = new DummyCamera();
			//camera.addView(view);
			//world.createInstance(camera);
			world.findInstances(AbstractCamera.class).iterator().next().addView(view);
			
			//box.addItem(container);
			return world;
		} catch (Exception e) {
			Debug.report(e);
			return null;
		}
	}
	
	@Override protected void loadSandBox(DefaultSandBox box) {
		// Initialize the sand box
		box.setBackgroundColor(Color.cyan);
		equipmentIndex = 0;
		Rectangle r = new Rectangle();
		box.getBoundary(r);
		
		// Add a cursor
		SandBoxCursor cursor = new SandBoxCursor();
		box.addItem(cursor);
	
		// Create the equipment
		Gasoline gasoline = new Gasoline();
		gasoline.setPosition(r.getMaxX() - 128, r.getMaxY() - 64);
		Electrolysis electrolysis = new Electrolysis();
		electrolysis.setPosition(r.getMaxX() - 128, r.getMaxY() - 128);
		equipment = new SandBoxItem[] {gasoline, electrolysis};
		box.addItem(equipment[equipmentIndex]);
		
		// Create buttons
		NextButton next = new NextButton(box);
		next.setPosition(r.getMaxX() - 48, r.getMaxY() - 48);
		box.addItem(next);
		PreviousButton previous = new PreviousButton(box);
		previous.setPosition(r.getMaxX() - 208, r.getMaxY() - 48);
		box.addItem(previous);
		
		// Add cells
		AnimalCell ac = new AnimalCell();
		ac.setPosition(96, 64);
		box.addItem(ac);
		PlantCell pc = new PlantCell();
		pc.setPosition(208, 80);
		box.addItem(pc);
		
		// Add molecule spawner
		SandBoxMachine m = new SandBoxMachine();
		m.addPart(new MachinePart(Resources.getTextureSet("machine_box_01"),0,0));
		m.addPart(new MachinePart(Resources.getTextureSet("machine_box_01"),32,0));
		m.addPart(new MachinePart(Resources.getTextureSet("machine_gear_01"),-32,-16));
		m.addPart(new MachinePart(Resources.getTextureSet("machine_box_02"),-32,0));
		m.setPosition(256, r.getMaxY()-r.getMinY()-16);
		box.addItem(m);
		MoleculePipe pipe = new MoleculePipe();
		pipe.setPosition(256, r.getMaxY()-r.getMinY()-48);
		box.addItem(pipe);
		Timer t = new Timer(120);
		t.addListener(new TimerListenerImpl(pipe,box));
		t.start(box.getWorld());
	}

	@Override protected void onBegin(WorldArea world) {
		// TODO Auto-generated method stub
		
	}

	@Override protected void onEnd(WorldArea world) {
		// TODO Auto-generated method stub
		
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** A next button. **/
	private final class NextButton extends SandBoxButton {
		
		private final SandBox box;

		public NextButton(SandBox box) {
			super(SandBoxButton.Type.RIGHT);
			this.box = box;
		}

		@Override public void onPress() {
			box.removeItem(equipment[equipmentIndex]);
			int index = equipmentIndex < equipment.length-1 ? equipmentIndex + 1 : 0; 
			box.addItem(equipment[index]);
			equipmentIndex = index;
			System.out.println(index);
		}
		
	}
	
	/** A next button. **/
	private final class PreviousButton extends SandBoxButton {
		
		private final SandBox box;

		public PreviousButton(SandBox box) {
			super(SandBoxButton.Type.LEFT);
			this.box = box;
		}

		@Override public void onPress() {
			box.removeItem(equipment[equipmentIndex]);
			int index = equipmentIndex > 0 ? equipmentIndex - 1 : equipment.length-1; 
			box.addItem(equipment[index]);
			equipmentIndex = index;
			System.out.println(index);
		}
		
	}
	
	/** A timer used to spawn molecules. **/
	private final class TimerListenerImpl implements TimerListener {
		
		private final SandBoxSpawner<?> spawner;
		private final SandBox box;
		
		public TimerListenerImpl(SandBoxSpawner<?> spawner, SandBox box) {
			this.spawner = spawner;
			this.box = box;
		}

		@Override public void onAlarm(Timer timer, WorldArea world) {
			timer.reset(150);
			box.addItem(spawner.spawn());
		}
		
	}

}
